Repository navigation
XL-0-SERVICE (parked): reproduce the shell service-emission fabrication — stdout bound to every declared output field, unboxed error arm - #9867
Conversation
…h a three-output known-hole probe The shell service-emission path in 05_emit_rust binds `stdout` to EVERY declared output field, whatever source the declaration named, and returns a bare String from the error arm against a declared Box<dyn std::error::Error>. Both emit Rust that does not compile, with zero diagnostics. This commit lands the reproduction only -- the lane was parked by the operator before the repair (it does not reduce the typeck count). The probe is a §4b(4) known-hole probe: green today asserting the WRONG behavior, and it must flip to the refusal assertion when the wall lands. The three-output fixture is the load-bearing part. Two fields cannot distinguish "wrong tuple index" from "the declared source never arrived"; three can, and the ABSENCE of the emitted `let stderr = ...` prelude is the positive evidence that the `from "stderr"` field was invisible rather than mis-ordered. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SKidppJZFSPywEdbVGJ1Ex
Loss site pinned: the
|
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 90bd2fefe9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| #[test] | ||
| fn shell_service_output_projection_fabricates_stdout_known_hole_probe() { |
There was a problem hiding this comment.
Add the probe to the compiler-tests authority
This edits only the generated compiler_tests.rs mirror, while emit_compiler_tests_module recreates that path from v1.compiler.compiler_tests_rust::compiler_tests_source(), whose producer list contains no version of this probe. Consequently the required-regen comparison will report drift, and any regeneration will delete the test. Define and enroll the probe in src/v1/compiler_tests_rust.dag, then regenerate this mirror.
Useful? React with 👍 / 👎.
| #[test] | ||
| fn shell_service_output_projection_fabricates_stdout_known_hole_probe() { |
There was a problem hiding this comment.
Enroll the probe in the retained test crate
Checked src/v2/workflow/ci_v1_compiler_tests_compile_gate_emit.dag: the CI execution gate runs cargo test -p v1-compiler-tests --release, but this test belongs to the dependency crate's #[cfg(test)] mod compiler_tests. Cargo does not enable a dependency's unit-test configuration while testing the separate v1-compiler-tests package, so this probe is never executed by that gate and provides no signal when the defect changes. Put the probe in the retained package under src/v1/tests or explicitly enroll the v1-compiler lib-test target.
Useful? React with 👍 / 👎.
| assert!( | ||
| emitted.contains("Ok((stdout.clone(), stdout.clone(), stdout.clone()))"), |
There was a problem hiding this comment.
Assert the unboxed error arm in the probe
The probe and its surrounding description claim to reproduce both stdout fabrication and the bare-String error arm, but the assertions inspect only the success tuple and missing stderr prelude. If the error arm changes independently, this test remains green and supplies no evidence that the second reported defect is present or repaired. Add a discriminating assertion for the emitted Err(...) expression, including the currently missing boxing conversion.
Useful? React with 👍 / 👎.
…egenerate the stage0 mirror
The parked commit hand-wrote the probe into src/v1/stage0/src/compiler_tests.rs,
which is a GENERATED file -- the emitted-population manifest names it, so the next
regeneration would have silently deleted it. The authority for that surface is
src/v1/compiler_tests_rust.dag.
This commit authors ct_shell_service_output_projection_known_hole_probe_test()
there, enrolls it in compiler_tests_source(), and carries both generated
projections that follow from it:
- src/v1/stage0/src/v1_compiler_compiler_tests_rust.rs (the mirror of the
generator module itself), and
- src/v1/stage0/src/compiler_tests.rs (the generator's own output), where the
probe now sits at the position compiler_tests_source() places it rather than
at end-of-file.
Both were taken from --required-regen candidate bytes, not hand-edited: round one
reported exactly one generated-surface drift (v1_compiler_compiler_tests_rust.rs),
and round two -- with the seed rebuilt from that mirror -- reported exactly one
more (compiler_tests.rs). The probe's own bytes are unchanged; it still asserts
today's WRONG behavior and must flip when the wall lands.
#9867 and this branch each added a witness to compiler_tests_rust.dag. The .dag authority merged cleanly and carries both; only the two generated projections conflicted, and the driver refused them with no conflict markers and ours-side bytes in the worktree. Regenerated from the merged authority rather than picking a side. The candidate carries both ct_import_lines_follow_resolved_binding_identity_test and ct_shell_service_output_projection_known_hole_probe_test -- taking either side would have dropped the other silently. Two rounds were needed because v1_compiler_compiler_tests_rust.rs is the emitter and compiler_tests.rs is what it emits, so each install reveals the next layer on rebuild. first_generation_equal=true at round 3. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BDnHQs9oE5AKJXe1vReU8v
Census: where the Rust emitter guesses a callee's INSTANTIATED parameter typeRequested by gentle-koi-869 after their target_carriers.rs:105 and v2_compiler_compile.rs:288 Censused from the EMITTER SOURCE, at symbol grain, not from the rustc error list -- the error list The six decision sites (all in
|
PARKED by operator directive (typeck-to-zero is the only funded priority). This PR carries the REPRODUCTION ONLY, not the repair.
src/v1/05_emit_rust.dag(emit_shell_return,emit_shell_channel_expr,emit_exit_code_handling,emit_exit_arm) plus the shared vocabulary inv1.compiler.emit, regeneratesrc/v1/stage0/src/v1_compiler_emit_rust.rsfrom the merged authority (never merge-resolve the mirror), and flip the probe in this PR to assert the refusal.The defect
src/v1/05_emit_rust.dag's shell service-emission path emits Rust that does not compile, with zero diagnostics. Reproduced by execution —compile_sourceson an inline module,RenderTarget::Rust, run remotely on BuildBuddy.Declaration:
Emitted, verbatim:
Two type errors in four lines. This is DESIGN §5's fabricated-plausible-output arm applied to the emitter: a producer that cannot answer a question answers anyway.
Refuted hypothesis — the binding rule is none of the three candidates
The handoff proposed the rule was "always the first output", "always the last", or "always the one named stdout". It is none of them. It is
stdoutfor every field, unconditionally, because the declared source never reaches the renderer:child_from_keyreturnsAbsentfor all three fields, and each then falls throughAbsent => "stdout"inemit_shell_returnand the trailingelse { stdout.clone() }inemit_shell_channel_expr.The three-output fixture is what made this decidable, and the evidence is an absence. With two fields, "always the first output" and "always stdout" emit identical bytes — the originally observed case could not separate them. With three, they diverge. And the decisive datum is the missing
let stderr = String::from_utf8_lossy(&output.stderr).to_string();prelude line: the renderer emits that line only when some field claims the stderr channel, so its absence proves thefrom "stderr"field was invisible to the renderer, not merely mis-ordered.So there are two defects stacked, and neither alone is the repair:
fromkey is lost somewhere between parse (parse_optional_from_keymints it as afrom_keyproperty) and the shell renderer — note the interpreter'smap_shell_outputsreads the same property off the same children throughextract_from_keyand works, so the loss is on the emit path;stdoutinstead of refusing, which is exactly what made (1) silent for as long as it has existed.Fixing only (2) turns 209 working-looking declarations into refusals. Fixing only (1) leaves the fabricating arm armed for the next fact that goes missing.
Blast radius — latent, but armed
Verified three ways, not assumed:
DryRunMode,dry_run.is_dry_run()andoutput.status.code().unwrap_or(-1)each occur in exactly one file,src/v1/stage0/src/v1_compiler_emit_rust.rs, and there only inside the emitter's own template strings.servicedeclarations exist undersrc/v1, which is the closureregenseeds into stage0. This path has therefore never produced a committed mirror.from "exit_success"(i.e. are multi-field). Every one emits non-compiling Rust the moment its module enters an emitted closure — which is a thing v2 migration does routinely. Latent is not safe; it is armed.Channel-vocabulary census (needed before the coproduct can be closed)
The repair replaces a trailing
elsewith an exhaustive match, so everyfrom "…"string in the corpus must be a declared member or it refuses. Enumerated first rather than discovered one refusal at a time. Re-derive with:(brace-tracking extractor; 386 operations found — 296 shell, 76 rest, 6 file, 8 with no transport)
Distinct shell from-keys — 8, and only 4 are realized by the Rust emitter today:
stdoutexit_successstderrexit_codestdoutstdout_linesstderr_truncatedstdoutstderr_total_bytesstdoutstderr_retained_bytesstdoutTwo consequences the repair must carry:
exit_codeis 107 declarations silently emittingstdout.clone()for an integer channel. This is the largest single instance of the fabrication and was invisible because theelsearm answered for it.fromkey (checked: 0 of 296). So closing the coproduct refuses nothing that exists today, provided all 8 members are modeled. No typos or invented channels were found — the wall exposes no pre-existing authoring errors, only the emitter's own unrealized channels.v1_interpreter::shell_evidence_value+map_shell_outputs) already models 13 channels including byte-accounting ones (*_total_bytes,*_retained_bytes,*_truncated,*_digest_hex). That is a §3 fork: one fact — which shell channels exist — implemented twice, unequally. The byte-accounting channels are genuinely not realizable byCommand::output()(they only differ under the interpreter's bounded drain), so the honest emitter arm for them is a typed located refusal, not a value.The error arm is a §3 fork, not a missing
.into()emit_exit_code_handlingandemit_exit_armboth emitErr(<String expr>)against a declaredBox<dyn std::error::Error>. The REST arm ~200 lines above, in the same emitter, writesErr(format!(…).into()). One fact — how this emitter returns an error — is implemented twice and the two implementations disagree. The repair is one shared error-return authority read by both arms, not a second.into(); otherwise the fork stands with both halves correct today and free to diverge again.What is in this PR
One
#[test]insrc/v1/stage0/src/compiler_tests.rs: a §4b(4) known-hole probe, green today, asserting the wrong behavior (Ok((stdout.clone(), stdout.clone(), stdout.clone())), and the absent stderr prelude). When the wall lands it must flip to the refusal assertion and stay enrolled as a permanent regression control. It is not a passing check of correct behavior and must not be read as one.Sequencing note for the resumer
Three lanes were editing
05_emit_rust.dagconcurrently.#9850(bold-carp-449) is in main and merged here.#9854(stern-ferret-752) and#9862(bold-carp-449, a shared predicate that renames symbols in this file) were both still open at park time — check them before touching the authority. The mirrorv1_compiler_emit_rust.rsmust never be merge-resolved: whoever integrates second regenerates it from the merged.dagauthority.